/*
 * layui的初始化模块可以理解为，引入这个模块的js文件
  * 值得注意的是：layui的模块之间存在依赖关系，例如引入了table模块，它会layui/lay/moudules/table.js
  * 这个文件引入进来，并且它还会将这个模块所依赖的其他模块自动加入进来，
  * 实际引入的模块有：table、form、jquery、layer、laypage、laytpl、util，7个js文件
  * 所以我仅仅初始化了table模块，却能获得form、jquery、layer的模块对象
 */
//layui初始化表格模组
layui.use(['table', 'tree'], function () {
  //获得模块对象
  var table = layui.table;
  var form = layui.form;
  var $ = layui.jquery;
  var layer = layui.layer;
  var tree = layui.tree;

  //数据表格渲染
  table.render({
    elem: '#roleAllotResourceTable'
    ,url:'system/power/roles'
    ,method: 'get'
    ,where: {} // 你额外要携带数据，以键值对的方式存入
    ,cellMinWidth: 160 // 全局定义所有常规单元格的最小宽度（默认：60）
    ,cols: [[
      {type:'numbers', fixed: 'left'} // 序号
      ,{type: 'radio', fixed: 'left'} // 复选框
      ,{field:'roleName', title:'角色名'}
      ,{field:'subsetName', title:'组织类型名'}
    ]]
    ,page: true // 开启分页
    ,limit: 10 // 每页显示的条数
    ,limits: [5,10,20,50,100] // 每页条数的选择项
    ,loading: true // 是否显示加载条(切换分页的时候显示）
    ,id: 'roleAllotResourceTable' // 设定容器唯一 id
    ,even: false // 隔行变色
  });
  
  //资源树形数据
  var resourceTreeData = null;
  //能勾选的资源ID数组
  var canCheckedResourceIds = [];
  
  //发送请求查询所有资源
  $.ajax({
	  async: false,
	  url:"system/power/allResource",
	  type: "get",
	  success:function(result){
		  //返回一个处理过后的新数组
	  	  let newData = result.map(function(item) {
	  		  //改成layui所需要的格式
	  		  return {
	  			  "id":item.resourceId,
			      "title":item.resourceName,
			      "parentId":item.parentId,
			      "children":null,
			      "spread": (item.parentId == null ? true : false) //展开顶层资源
			  }
		  });
		  //将扁形数据转为树形数据 将资源树放入全局
	  	  resourceTreeData = toTreeData(newData, 'id', 'parentId', 'children', '0000000000000000');
	  	  /*
	  	   *  时隔很久，如果你再次看到这段代码，却无法理解为什么要这样写
	  	   *  请不要怪自己，因为那个时候的他真的想不出更好的解决方案了 ^_^
	  	   *  2019-12-05
	  	   */
	  	  var canCheckedResource = function(data){
	  		  for (let i in data) {
	  			  if (data[i].children != null && data[i].children.length > 0) {
	  				  //递归
	  				  canCheckedResource(data[i].children);
	  			  } else {
	  				  canCheckedResourceIds.push(data[i].id);
	  			  }
	  		  }
	  	  }
	  	  //调用以上方法
	  	  canCheckedResource(resourceTreeData);
	  }
  });
  
  //搜索表单提交
  form.on('submit(resourceSearchBtn)', function(data){
	  //隐藏右侧资源树
	  $(".roleResource_table_right").hide();
	  //表格重载
	  table.reload('roleAllotResourceTable', {
		  where: { //设定异步数据接口的额外参数，任意设
			  roleName: data.field.roleName
		  }
		  ,page: {
			  curr: 1 //重新从第 1 页开始
		  }
	  });
	  return false; //阻止表单跳转。如果需要表单跳转，去掉这段即可。
  });
  
  //重置按钮点击
  $("#reset").click(function(){
	  //表格重载
	  table.reload('roleAllotResourceTable', {where: null});
	  //隐藏右侧资源树
	  $(".roleResource_table_right").hide();
  });
  
  //渲染指定角色拥有的资源树
  var roleSetResource = function(roleId){
	  //渲染树形表格
	  tree.render({
	      elem: '#resourceTree'
	      ,data: resourceTreeData // 数据源
	      ,onlyIconControl: false // 是否只能通过左侧的图标控制开合
	      ,showLine: true // 是否显示连接线，不显示就是三角形
	      ,showCheckbox: true // 是否显示复选框
	      ,id: 'resourceTree' //定义索引，唯一标识
    	  ,oncheck: function(obj){
    		    var btnType = obj.data.title.substring(0, 2); // 当前点击的复选框的标题
    		    var elem = obj.elem; // 当前点击的复选框的元素对象
    		    if (btnType == "添加" || btnType == "修改" || btnType == "删除") {
    		    	if (obj.checked == true) {
    		    		//遍历当前层级的所有复选框的标题的元素
    		    		elem.parent().find(".layui-tree-txt").each(function(){
		    				//如果当前复选框的标题包含查看
    		    			if ($(this).text().indexOf("查看") != -1) {
    		    				//获取这个查看复选框的值
        		    			var selectBtnId = $(this).prevAll("input").val();
        		    			//勾选这个复选框
        		    			tree.setChecked('resourceTree', parseInt(selectBtnId));
        		    		}
        		    	});
    		    	}
    		    } else if (btnType == "查看") {
    		    	if (obj.checked == false) {
    		    		//遍历当前层级的所有复选框对象
    		    		elem.parent().children().each(function(){
    		    			//获取到隐藏的checkbox input对象
    		    			var input = $(this).children('.layui-tree-entry').find('input[same="layuiTreeCheck"]');
    		    			//如果这个复选框的checkbox input的时选中状态
    		    			if (input[0].checked == true) {
    		    				//因为当前元素是选中状态，所以我们调用一次点击方法就相当于将元素设置为取消选中
    		    				input.next().click(); // click() 是layui元素自带的事件 调用就选中，再调用就取消选中
    		    			}
        		    	});
    		    	}
    		    }
    	  }
	  });
	  //获取要勾选的资源ID
	  var resourceIds = findRoleHasResourceId(roleId);
	  //定义一个用来存储要勾选的资源ID的数组
	  var checkedResourceIds = [];
	  //将树形数据的要勾选的资源ID拿出来
	  for (let i in resourceIds) {
		  if(canCheckedResourceIds.indexOf(resourceIds[i]) != -1){
			  checkedResourceIds.push(resourceIds[i]);
		  }
	  }
	  //勾选节点
	  tree.setChecked('resourceTree', checkedResourceIds);
  }
  
  //数据表格单选框选中事件
  table.on('radio(roleAllotResourceTable)', function(obj){
	  //渲染该角色拥有的资源树
	  roleSetResource(obj.data.roleId);
	  //显示资源树
	  $(".roleResource_table_right").show();
  });
  
  //树形资源弹出框保存按钮点击事件
  $("#save").click(function(){
	  //获取树选中的数据              
	  var treeCheckData = tree.getChecked('resourceTree');
	  
	  //获取选择的角色的ID
	  var roleId = table.checkStatus('roleAllotResourceTable').data[0].roleId;
	  if (roleId == null || roleId == "") {
		  layer.alert("请选择一个角色进行查看");
	  }
	  //用于存储所有选中的资源ID
	  var checkResourceIds = [];
	  //将树形数据的所有ID拿出来
	  var toFlatData = function(data){
		  //遍历
		  for (let i in data) {
			  //添加
			  checkResourceIds.push(data[i].id);
			  //判断
			  if (data[i].children != null && data[i].children.length > 0) {
				  //递归
				  toFlatData(data[i].children);
			  }
		  }
	  }
	  //调用获取树形数据里面的所有资源ID的方法
	  toFlatData(treeCheckData);
	  
	  //加载层 //0.1透明度的白色背景
	  //layer.load(1, {shade: [0.1, '#fff']});
	  layer.load(0, {shade: false});
	  //发送修改角色资源的请求 先删除角色所有的资源，再添加现有的资源
	  $.ajax({
		  async: false,
		  url:"system/power/roleResource",
		  type: "post",
		  traditional: true, // 序列化参数，数组才能直接接收
		  data: {
			  _method: "PUT",
			  roleId: roleId,
			  resourceIds: checkResourceIds
		  },
		  success:function(result){
			  //关闭所有的加载层
			  layer.closeAll('loading');
			  if (result == true) {
				  layer.msg("保存成功！", {icon: 1, time: 2500});
			  } else if (result == false) {
				  layer.msg("保存失败！", {icon: 1, time: 2500});
			  } else {
				  layer.msg("没有获取到角色ID为空", {icon: 1, time: 2500});
			  }
		  }
	  });
  });
});

/*
 *	根据角色ID查询改角色拥有的资源ID
 */
function findRoleHasResourceId(roleId) {
	  //某个角色所拥有的资源ID数组
	  var resourceIds = [];
	  //请求后台，根据角色ID查询资源ID
	  $.ajax({
		async: false,
		url:"system/power/roleHasResourceId?roleId="+roleId,
		type: "get",
		success:function(result){
			//先清空一次资源数组
			resourceIds.length = 0;
			//将查询到的资源ID加入资源ID数组
			for (let i in result) {
				resourceIds.push(result[i]);
		    }
		}
	  });
	  return resourceIds;
}

/* 
	扁形数据转为树形数据
	source：要转换的数据源
	idName: id的字段名
	parentIdName: 父id的字段名
	children: 子元素集合字段名
	parentId: 要显示数据的顶层id
*/
function toTreeData(source, idName, parentIdName, childrenName, parentId){   
    let cloneData = JSON.parse(JSON.stringify(source));
    return cloneData.filter(father => {
        let branchArr = cloneData.filter(child => father[idName] == child[parentIdName]);
        branchArr.length > 0 ? father[childrenName] = branchArr : '';
        return father[parentIdName] == parentId;
    });
}

